package utils;

import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.util.LinkedList;

/**
* Permet de gerer l'ordre du focus des elements d'un composant a l'aide d'une liste chainee.
* L'ordre d'ajout determine l'ordre du focus, mais les composants pas "enable" ne sont pas pris
* en compte.
* @author Bruno da Silva
* @since 15.06.2007
* @version 1.0
*/
public class MapFocusTraversalPolicy extends FocusTraversalPolicy {
	/**
	 * Liste des composants
	 */
	private LinkedList<Component> componentList = new LinkedList<Component>();
	
	/**
	 * Ajoute un composant a la liste gerant le focus
	 * @param Composant a ajouter a la liste
	 */
	public void addComponent(Component component){
		componentList.add(component);
	}

	/**
	 * Retourne le prochain composant a avoir le focus
	 * @param Composant parent contenant les elements de la liste
	 * @param Composant possedant actuellement le focus
	 * @return Le prochain composant a avoir le focus
	 */
	public Component getComponentAfter(Container parent, Component component) {
		// Position dans la liste du composant ayant actuellement le focus
		int position = componentList.indexOf(component);
		// Gere la circularite de la liste
		position = position == componentList.size()-1?-1:position;
		// Obtient le prochain composant dans la liste
		Component nextComponent = componentList.get(position+1);
		
		// Retourne le prochain composant s'il est active
		if (nextComponent.isEnabled())
			return nextComponent;
		
		// Appel recursif si le prochain composant n'est pas active
		return getComponentAfter(parent, nextComponent);
	}
	
	/**
	 * Retourne le composant precedant a avoir le focus
	 * @param Composant parent contenant les elements de la liste
	 * @param Composant possedant actuellement le focus
	 * @return Le precedant composant a avoir le focus
	 */
	public Component getComponentBefore(Container parent, Component component) {
		// Position dans la lise du composant ayant actuellement le focus
		int position = componentList.indexOf(component);
		// Gere la circularite de la liste
		position = position == 0? componentList.size():position;
		// Obtient le precedant composant dans la liste
		Component beforeComponent = componentList.get(position-1);
		
		// Retourne le composant precedant d'il est active
		if (beforeComponent.isEnabled())
			return beforeComponent;
		
		// Appel recursif si le precedant composant n'est pas active
		return getComponentBefore(parent, beforeComponent);
	}
	
	/**
	 * Retourne le composant ayant le focus par defaut
	 * @param Composant parent contenant les elements de la liste
	 * @return Composant ayant le focus par defaut
	 */
	public Component getDefaultComponent(Container parent) {
		return componentList.get(0);
	}
	
	/**
	 * Retourne le premier composant de la liste
	 * @param Composant parent contenant les elements de la liste
	 * @return Premier composant de la liste
	 */
	public Component getFirstComponent(Container parent) {
		return componentList.get(0);
	}
	
	/**
	 * Retourne le dernier composant de la liste
	 * @param Composant parent contenant les elements de la liste
	 * @return Dernier composant de la liste
	 */
	public Component getLastComponent(Container parent) {
		return componentList.get(componentList.size() -1);
	}
}